type
?object
?type
and object
related?Most of this talk is based on this article by Shalabh Chaturvedi.
While we introduce many different objects, we only use two kinds of relationships:
An object is an entity with the following characteristic properties:
objectname.attributename
).2
has a type int
and the object "joe"
has a type string
.
In [1]:
two = 2
print(type(two))
In [2]:
print(type(type(two)))
In [3]:
print(type(two).__bases__)
In [4]:
print(dir(two))
And I mean everything. Even things that are "primitive types" in other languages.
And more importantly: You can treat every programming construct in a uniform and consistent way
def
, Python creates a function object.map
function takes a function and an iterable and applies the function to each item in the iterable.class
, Python executes it and creates an object.Therefore: Objects are instances of classes, classes are instances of metaclasses and metaclasses are instances of themselves.
MyClass = MetaClass()
MyObject = MyClass()
Metaclasses are deeper magic than 99% of users should ever worry about. If you wonder whether you need them, you don’t (the people who actually need them know with certainty that they need them, and don’t need an explanation about why). Tim Peters
type
?type
? The good old function that lets you know what type an object is.type
can also create classes on the fly. type
can take the description of a class as parameters, and return a class as type(name, bases, dct)
.name
is a string giving the name of the class to be constructed.bases
is a tuple giving the parent classes of the class to be constructed.dct
is a dictionary of the attributes and methods of the class to be constructed.Type
? Consistency with str
, the class that creates strings objects, and int
the class that creates integer objects. type
is just the class that creates class
objects.
In [5]:
class A:
pass
a = A()
print(type(a))
print(type(A))
print(A.__bases__)
In [6]:
A = type('A', (), {})
a = A()
print(type(a))
print(type(A))
print(A.__bases__)
print(isinstance(a, A), isinstance(a, object), issubclass(A, object))
In [7]:
def f():
"""My name is f."""
pass
print(type(f))
print(type(type(f)))
print(type(f).__bases__)
print(f.__doc__)
type
type
is the metaclass Python uses to create (i.e. instantiate) all classes and metaclasses, including type
itself.type
is actually its own metaclass. This is not something you could reproduce in pure Python, and is done by cheating a little bit at the implementation level.object
?object
is the class that all classes inherit from.object
are subclasses of themselves.object
are subclasses of object
. object.__bases__
is an empty tuple.object
will have object
in __bases__
in a class in their inheritance hierarchy.type
, object
, int
, str
, list
.1
, "hello"
, [1, 2, 3]
.type
and object
are two primitive objects of the system.objectname.__class__
exists for every object and points the type of the object.objectname.__bases__
exists for every type object and points the superclasses of the object. It is empty only for object
.
In [8]:
issubclass(type, object) # Recap rule #1
Out[8]:
In [9]:
issubclass(object, object) # Recap rule #1
Out[9]:
In [10]:
issubclass(object, type) # Recap rule #1
Out[10]:
In [11]:
isinstance(object, type) # Recap rule #2
Out[11]:
In [12]:
isinstance(type, type) # Recap rule #2
Out[12]:
In [13]:
isinstance(type, object) # Recap rule #3
Out[13]:
In [14]:
isinstance(object, object) # Recap rule #3
Out[14]:
In [15]:
from IPython.display import Image, display
display(Image(url='figures/mind_blown.gif', width=400))
Ruby inherited the Perl philosophy of having more than one way to do the same thing. I inherited that philosophy from Larry Wall, who is my hero actually. Y. Matsumoto, creator of Ruby.
Matz chose to sacrifice first-class functions just so he could make parentheses optional.
Methods are a fundamental part of Ruby's syntax, but they are not values that Ruby programs can operate on. That is, Ruby's methods are not objects in the way that strings, numbers, and arrays are. From The Ruby Programming Language Book.